#ifndef BSP_W25QXX_H
#define BSP_W25QXX_H
#include "stm32f4xx.h"

// W25X系列/Q系列芯片列表
#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16
#define W25Q128 0XEF17

/**
 * 对于W25Q16 FLASH芯片
 */
#define SPI_FLASH_SECTOR_SIZE 512
#define SPI_FLASH_SECTOR_COUNT 2 * 1024 * 2 /* 25Q128, 前12M字节给FATFS占用 */
#define SPI_FLASH_BLOCK_SIZE 8              /* 每个BLOCK有8个扇区 */
#define SPI_FLASH_FATFS_BASE 0              /* FATFS 在外部FLASH的起始地址 从0开始 */

#define SPI2_CLK_ENABLE __HAL_RCC_SPI2_CLK_ENABLE()
#define GPIO_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE()

#define SPI_PORT GPIOB
#define SPI_CS_PIN GPIO_PIN_12
#define SPI_CS_SCK_CLK __HAL_RCC_GPIOB_CLK_ENABLE()

#define SPI_SCK_PIN GPIO_PIN_13
#define SPI_SCK_SCK_CLK __HAL_RCC_GPIOB_CLK_ENABLE()

#define SPI_MISO_PIN GPIO_PIN_14
#define SPI_MISO_SCK_CLK __HAL_RCC_GPIOB_CLK_ENABLE()

#define SPI_MOSI_PIN GPIO_PIN_15
#define SPI_MOSI_SCK_CLK __HAL_RCC_GPIOB_CLK_ENABLE()

#define W25QXX_CS_H SPI_PORT->BSRR = SPI_CS_PIN                  // 片选拉高
#define W25QXX_CS_L SPI_PORT->BSRR = (uint32_t)SPI_CS_PIN << 16U // 片选拉低

//////////////////////////////////////////////////////////////////////////////////
// 指令表
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F

uint16_t W25QXX_Init(void);
uint16_t W25QXX_ReadID(void);     // 读取FLASH ID
uint8_t W25QXX_ReadSR(void);      // 读取状态寄存器
void W25QXX_Write_SR(uint8_t sr); // 写状态寄存器
void W25QXX_Write_Enable(void);   // 写使能
void W25QXX_Write_Disable(void);  // 写保护
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);    // 读取flash
void W25QXX_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite); // 写入flash
void W25QXX_Erase_Chip(void);                                                     // 整片擦除
void W25QXX_Erase_Sector(uint32_t Dst_Addr);                                      // 扇区擦除
void W25QXX_Wait_Busy(void);                                                      // 等待空闲
void W25QXX_PowerDown(void);                                                      // 进入掉电模式
void W25QXX_WAKEUP(void);                                                         // 唤醒

#endif // BSP_W25QXX_H
